package cn.blnp.net.flowable.boot.utils;

import java.util.*;
import java.util.function.*;
import java.util.stream.Collectors;

/**
 * <h3></h3>
 *
 * @author <a href="mailto:blnp.yibin@qq.com">lyb</a>
 * @version 1.0
 * @since 2025/6/18 13:35
 */
public class ListUtils {

    // ================= 创建方法 =================

    /**
     * 创建空ArrayList
     */
    public static <T> List<T> newArrayList() {
        return new ArrayList<>();
    }

    /**
     * 创建指定初始容量的ArrayList
     */
    public static <T> List<T> newArrayList(int initialCapacity) {
        return new ArrayList<>(initialCapacity);
    }

    /**
     * 创建带预期大小的ArrayList（自动计算1.5倍容量）
     */
    public static <T> List<T> newArrayListWithExpectedSize(int expectedSize) {
        return new ArrayList<>((int) Math.min(expectedSize * 1.5, Integer.MAX_VALUE - 8));
    }

    /**
     * 创建LinkedList
     */
    public static <T> List<T> newLinkedList() {
        return new LinkedList<>();
    }

    /**
     * 创建不可变List
     */
    @SafeVarargs
    public static <T> List<T> of(T... elements) {
        return elements == null ? Collections.emptyList() : Arrays.asList(elements);
    }

    /**
     * 从数组创建List
     */
    public static <T> List<T> fromArray(T[] array) {
        return array == null ? new ArrayList<>() : new ArrayList<>(Arrays.asList(array));
    }

    /**
     * 从集合创建List
     */
    public static <T> List<T> fromCollection(Collection<T> collection) {
        return collection == null ? new ArrayList<>() : new ArrayList<>(collection);
    }

    // ================= 初始化方法 =================

    /**
     * 初始化指定大小的List，并用默认值填充
     */
    public static <T> List<T> init(int size, T defaultValue) {
        List<T> list = new ArrayList<>(size);
        for (int i = 0; i < size; i++) {
            list.add(defaultValue);
        }
        return list;
    }

    /**
     * 用生成器函数初始化List
     */
    public static <T> List<T> init(int size, IntFunction<T> generator) {
        List<T> list = new ArrayList<>(size);
        for (int i = 0; i < size; i++) {
            list.add(generator.apply(i));
        }
        return list;
    }

    // ================= 操作工具方法 =================

    public static <T> boolean isEmpty(List<T> list) {
        return list == null || list.isEmpty();
    }

    public static <T> boolean isNotEmpty(List<T> list) {
        return !isEmpty(list);
    }

    public static <T> List<T> distinct(List<T> list) {
        return isEmpty(list) ? new ArrayList<>() : new ArrayList<>(new LinkedHashSet<>(list));
    }

    public static <T> List<T> filter(List<T> list, Predicate<T> predicate) {
        return isEmpty(list) ? new ArrayList<>() : list.stream().filter(predicate).collect(Collectors.toList());
    }

    public static <T, R> List<R> map(List<T> list, Function<T, R> mapper) {
        return isEmpty(list) ? new ArrayList<>() : list.stream().map(mapper).collect(Collectors.toList());
    }

    @SafeVarargs
    public static <T> List<T> merge(List<T>... lists) {
        List<T> result = new ArrayList<>();
        for (List<T> list : lists) {
            if (isNotEmpty(list)) {
                result.addAll(list);
            }
        }
        return result;
    }

    public static <T> List<T> page(List<T> list, int pageNum, int pageSize) {
        if (isEmpty(list)) return new ArrayList<>();
        int fromIndex = (pageNum - 1) * pageSize;
        if (fromIndex >= list.size()) return new ArrayList<>();
        int toIndex = Math.min(fromIndex + pageSize, list.size());
        return list.subList(fromIndex, toIndex);
    }
}
